﻿#region 文件信息

// FileName: SoCafeShop/Sohobloo.SoAuth.Web/MefConfig.cs
// Author: Sohobloo
// CreateTime: 2013/06/30 4:55
// UpdateTime: 2013/06/30 5:03

#endregion

#region 引用

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Web;
using System.Web.Mvc;

#endregion

namespace Sohobloo.SoAuth.Web
{
    public static class MefConfig
    {
        #region 方法

        public static void RegisterSolver()
        {
            var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
            var solver = new MefDependencySolver(catalog);
            DependencyResolver.SetResolver(solver);
        }

        #endregion 方法
    }

    /// <summary>
    ///     MEF依赖关系解析类
    /// </summary>
    internal class MefDependencySolver : IDependencyResolver
    {
        #region 枚举

        private const string HttpContextKey = "MefContainerKey";
        private readonly ComposablePartCatalog _catalog;

        #endregion 枚举

        #region 属性

        public CompositionContainer Container
        {
            get
            {
                if (!HttpContext.Current.Items.Contains(HttpContextKey))
                {
                    HttpContext.Current.Items.Add(HttpContextKey, new CompositionContainer(_catalog));
                }
                var container = (CompositionContainer) HttpContext.Current.Items[HttpContextKey];
                HttpContext.Current.Application["Container"] = container;
                return container;
            }
        }

        #endregion 属性

        #region 构造

        public MefDependencySolver(ComposablePartCatalog catalog)
        {
            _catalog = catalog;
        }

        #endregion 构造

        #region 方法

        public object GetService(Type serviceType)
        {
            var contractName = AttributedModelServices.GetContractName(serviceType);
            return Container.GetExportedValueOrDefault<object>(contractName);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return Container.GetExportedValues<object>(serviceType.FullName);
        }

        #endregion 方法
    }
}